<template>
  <div class="flow-container">
    <div class="scale-slider">
      <el-icon class="btn el-icon-minus" @click="changeScale(-step)"><Minus /></el-icon>
      <span style="font-size:14px;">{{ scaleVal }}%</span>
      <el-icon class="btn el-icon-plus" @click="changeScale(step)"><Plus /></el-icon>
    </div>
    <FlowCard
      :verifyMode="verifyMode"
      :key="updateId"
      :data="data"
      @emits="eventReciver"
      :style="`transform: scale(${scaleVal / 100})`"
    />
    <PropPanel
      :value="activeData"
      :processData="data"
      @confirm="onPropEditConfirm"
      @cancel="onClosePanel"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, defineProps, defineEmits } from 'vue';
import FlowCard from "./FlowCard/index.vue";
import PropPanel from "./PropPanel/index.vue";
import { NodeUtils, getMockData } from "./FlowCard/util.js";

const props = defineProps(['tabName', 'conf']);
const emits = defineEmits(['startNodeChange']);

const data = ref<{} | null>(null);
const scaleVal = ref(100);
const step = 5;
const updateId = ref(0);
const activeData = ref<null | {}>(null);
const isProcessCmp = ref(true);
const verifyMode = ref(false);

onMounted(() => {
  let initialData = getMockData();

  if (typeof props.conf === 'object' && props.conf !== null) {
    Object.assign(initialData, props.conf.processData);
  }
  data.value = initialData;
});

const getData = (): Promise<{ formData: {} }> => {
  verifyMode.value = true;
  if (NodeUtils.checkAllNode(data.value)) {
    return Promise.resolve({ formData: data.value });
  } else {
    return Promise.reject({ target: props.tabName });
  }
};

const eventReciver = ({ event, args }: { event: string; args: any[] }): void => {
  console.log("事件：", event);
  console.log("参数", args);
  if (event === "edit") {
    activeData.value = args[0]; // 打开属性面板
    return;
  }
  NodeUtils[event](...args);
  forceUpdate();
};

const forceUpdate = (): void => {
  console.log("forceUpdate this.updateId", updateId.value);
  updateId.value += 1;
};

const changeScale = (val: number): void => {
  let v = scaleVal.value + val;
  if (v > 0 && v <= 200) {
    scaleVal.value = v;
  }
};

const onPropEditConfirm = (value: any, content: string): void => {
  activeData.value.content = content || '请设置条件表达式';
  let oldProp = activeData.value.properties;
  activeData.value.properties = value;
  if (NodeUtils.isConditionNode(activeData.value)) {
    if (value.priority !== oldProp.priority) {
      NodeUtils.resortPrioByCNode(activeData.value, oldProp.priority, data.value);
    }
  }
  if (NodeUtils.isConcurrentNode(activeData.value)) {
    if (value.priority !== oldProp.priority) {
      NodeUtils.resortPrioByCNode(activeData.value, oldProp.priority, data.value);
    }
  }
  if (NodeUtils.isStartNode(activeData.value)) {
    emits('startNodeChange', data.value);
  }
  onClosePanel();
  forceUpdate();
};

const onClosePanel = (): void => {
  activeData.value = null;
};

const isFilledPCon = (formIds?: string[]): boolean => {
  let res = false;
  const loopChild = (parent: any, callback: () => void) => {
    if (parent.childNode) loop(parent.childNode, callback);
  };
  const loop = (data: any, callback: () => void) => {
    if (res || !data) return;
    if (Array.isArray(data.conditionNodes)) {
      const used = data.conditionNodes.some((c: any) => {
        const cons = c.properties.conditions || [];
        return Array.isArray(formIds)
          ? cons.some((item: any) => formIds.includes(item.formId))
          : cons.length > 0;
      });
      if (used) callback();
      else data.conditionNodes.forEach((t: any) => loopChild(t, callback));
    }
    loopChild(data, callback);
  };
  loop(data.value, () => res = true);
  return res;
};

defineExpose({
  getData
});
</script>

<!--<style scoped lang="stylus">-->
<style scoped lang="scss">
.flow-container {
  display: inline-block;
  background: #f5f5f7;
  padding: 20px;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  text-align: center;
  overflow: auto;
}

.scale-slider {
  position: fixed;
  top: 150px;
  right: 50px;
  z-index: 99;
  display: flex;
  align-items: center;
  .btn {
    display: inline-block;
    padding: 4px;
    border: 1px solid #cacaca;
    border-radius: 3px;
    background: #FFF;
    margin-left: 10px;
    margin-right: 10px;
    cursor: pointer;
    height: 24px;
    width: 24px;
  }
}
</style>
